package edu.unf.cen6940.service;

import edu.unf.cen6940.dao.CategoryDAO;
import edu.unf.cen6940.dao.FacultyresearchDAO;
import edu.unf.cen6940.dao.ThesisDAO;

import edu.unf.cen6940.domain.Category;
import edu.unf.cen6940.domain.Facultyresearch;
import edu.unf.cen6940.domain.Thesis;

import java.util.List;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import org.springframework.transaction.annotation.Transactional;

/**
 * Spring service that handles CRUD requests for Category entities
 * 
 */

@Service("CategoryService")
@Transactional
public class CategoryServiceImpl implements CategoryService {

	/**
	 * DAO injected by Spring that manages Category entities
	 * 
	 */
	@Autowired
	private CategoryDAO categoryDAO;

	/**
	 * DAO injected by Spring that manages Facultyresearch entities
	 * 
	 */
	@Autowired
	private FacultyresearchDAO facultyresearchDAO;

	/**
	 * DAO injected by Spring that manages Thesis entities
	 * 
	 */
	@Autowired
	private ThesisDAO thesisDAO;

	/**
	 * Instantiates a new CategoryServiceImpl.
	 *
	 */
	public CategoryServiceImpl() {
	}

	/**
	 * Load an existing Category entity
	 * 
	 */
	@Transactional
	public Set<Category> loadCategorys() {
		return categoryDAO.findAllCategorys();
	}

	/**
	 */
	@Transactional
	public Category findCategoryByPrimaryKey(Integer categoryId) {
		return categoryDAO.findCategoryByPrimaryKey(categoryId);
	}

	/**
	 * Delete an existing Facultyresearch entity
	 * 
	 */
	@Transactional
	public Category deleteCategoryFacultyresearchs(Integer category_categoryId, Integer related_facultyresearchs_facultyResearchId) {
		Facultyresearch related_facultyresearchs = facultyresearchDAO.findFacultyresearchByPrimaryKey(related_facultyresearchs_facultyResearchId, -1, -1);

		Category category = categoryDAO.findCategoryByPrimaryKey(category_categoryId, -1, -1);

		related_facultyresearchs.getCategories().remove(category);
		category.getFacultyresearchs().remove(related_facultyresearchs);

		facultyresearchDAO.remove(related_facultyresearchs);
		facultyresearchDAO.flush();

		return category;
	}

	/**
	 * Save an existing Category entity
	 * 
	 */
	@Transactional
	public void saveCategory(Category category) {
		Category existingCategory = categoryDAO.findCategoryByPrimaryKey(category.getCategoryId());

		if (existingCategory != null) {
			if (existingCategory != category) {
				existingCategory.setCategoryId(category.getCategoryId());
				existingCategory.setCategoryDescription(category.getCategoryDescription());
			}
			category = categoryDAO.store(existingCategory);
		} else {
			category = categoryDAO.store(category);
		}
		categoryDAO.flush();
	}

	/**
	 * Delete an existing Thesis entity
	 * 
	 */
	@Transactional
	public Category deleteCategoryThesises(Integer category_categoryId, Integer related_thesises_thesisId) {
		Thesis related_thesises = thesisDAO.findThesisByPrimaryKey(related_thesises_thesisId, -1, -1);

		Category category = categoryDAO.findCategoryByPrimaryKey(category_categoryId, -1, -1);

		related_thesises.getCategories().remove(category);
		category.getThesises().remove(related_thesises);

		thesisDAO.remove(related_thesises);
		thesisDAO.flush();

		return category;
	}

	/**
	 * Return all Category entity
	 * 
	 */
	@Transactional
	public List<Category> findAllCategorys(Integer startResult, Integer maxRows) {
		return new java.util.ArrayList<Category>(categoryDAO.findAllCategorys(startResult, maxRows));
	}

	/**
	 * Delete an existing Category entity
	 * 
	 */
	@Transactional
	public void deleteCategory(Category category) {
		categoryDAO.remove(category);
		categoryDAO.flush();
	}

	/**
	 * Return a count of all Category entity
	 * 
	 */
	@Transactional
	public Integer countCategorys() {
		return ((Long) categoryDAO.createQuerySingleResult("select count(o) from Category o").getSingleResult()).intValue();
	}

	/**
	 * Save an existing Facultyresearch entity
	 * 
	 */
	@Transactional
	public Category saveCategoryFacultyresearchs(Integer categoryId, Facultyresearch related_facultyresearchs) {
		Category category = categoryDAO.findCategoryByPrimaryKey(categoryId, -1, -1);
		Facultyresearch existingfacultyresearchs = facultyresearchDAO.findFacultyresearchByPrimaryKey(related_facultyresearchs.getFacultyResearchId());

		// copy into the existing record to preserve existing relationships
		if (existingfacultyresearchs != null) {
			existingfacultyresearchs.setFacultyResearchId(related_facultyresearchs.getFacultyResearchId());
			existingfacultyresearchs.setTitle(related_facultyresearchs.getTitle());
			existingfacultyresearchs.setResearchDescription(related_facultyresearchs.getResearchDescription());
			existingfacultyresearchs.setResearchStatus(related_facultyresearchs.getResearchStatus());
			existingfacultyresearchs.setMinumumRequirements(related_facultyresearchs.getMinumumRequirements());
			related_facultyresearchs = existingfacultyresearchs;
		} else {
			related_facultyresearchs = facultyresearchDAO.store(related_facultyresearchs);
			facultyresearchDAO.flush();
		}

		related_facultyresearchs.getCategories().add(category);
		category.getFacultyresearchs().add(related_facultyresearchs);
		related_facultyresearchs = facultyresearchDAO.store(related_facultyresearchs);
		facultyresearchDAO.flush();

		category = categoryDAO.store(category);
		categoryDAO.flush();

		return category;
	}

	/**
	 * Save an existing Thesis entity
	 * 
	 */
	@Transactional
	public Category saveCategoryThesises(Integer categoryId, Thesis related_thesises) {
		Category category = categoryDAO.findCategoryByPrimaryKey(categoryId, -1, -1);
		Thesis existingthesises = thesisDAO.findThesisByPrimaryKey(related_thesises.getThesisId());

		// copy into the existing record to preserve existing relationships
		if (existingthesises != null) {
			existingthesises.setThesisId(related_thesises.getThesisId());
			existingthesises.setTitle(related_thesises.getTitle());
			existingthesises.setAbstract_(related_thesises.getAbstract_());
			existingthesises.setProposalAttempts(related_thesises.getProposalAttempts());
			existingthesises.setDefenseAttempts(related_thesises.getDefenseAttempts());
			existingthesises.setStartDate(related_thesises.getStartDate());
			existingthesises.setDoi(related_thesises.getDoi());
			related_thesises = existingthesises;
		} else {
			related_thesises = thesisDAO.store(related_thesises);
			thesisDAO.flush();
		}

		related_thesises.getCategories().add(category);
		category.getThesises().add(related_thesises);
		related_thesises = thesisDAO.store(related_thesises);
		thesisDAO.flush();

		category = categoryDAO.store(category);
		categoryDAO.flush();

		return category;
	}
}
